<template>
  <div class="file-upload-drag-drop">
    <div 
      class="upload-area"
      :class="{ 
        'drag-over': isDragOver,
        'uploading': isUploading,
        'disabled': disabled
      }"
      @drop="handleDrop"
      @dragover="handleDragOver"
      @dragenter="handleDragEnter"
      @dragleave="handleDragLeave"
      @click="triggerFileSelect"
    >
      <input
        ref="fileInput"
        type="file"
        multiple
        :accept="accept"
        @change="handleFileSelect"
        style="display: none"
      />
      
      <div class="upload-content">
        <div class="upload-icon">
          <el-icon v-if="!isUploading" size="48">
            <UploadFilled />
          </el-icon>
          <el-icon v-else size="48" class="rotating">
            <Loading />
          </el-icon>
        </div>
        
        <div class="upload-text">
          <h3 v-if="!isUploading">{{ title }}</h3>
          <h3 v-else>正在上传文件...</h3>
          <p v-if="!isUploading">{{ description }}</p>
          <p v-else>{{ uploadProgress }}% 已完成</p>
        </div>
        
        <div class="upload-tips">
          <p>支持格式：{{ acceptText }}</p>
          <p>单个文件最大：{{ maxSizeText }}</p>
        </div>
      </div>
      
      <!-- 上传进度条 -->
      <div v-if="isUploading" class="upload-progress">
        <el-progress 
          :percentage="uploadProgress" 
          :stroke-width="6"
          :show-text="false"
        />
      </div>
    </div>
    
    <!-- 文件列表 -->
    <div v-if="fileList.length > 0" class="file-list">
      <h4>待上传文件 ({{ fileList.length }})</h4>
      <div class="file-items">
        <div 
          v-for="(file, index) in fileList" 
          :key="index"
          class="file-item"
        >
          <div class="file-info">
            <el-icon class="file-icon">
              <Document />
            </el-icon>
            <div class="file-details">
              <div class="file-name">{{ file.name }}</div>
              <div class="file-size">{{ formatFileSize(file.size) }}</div>
            </div>
          </div>
          
          <div class="file-actions">
            <el-button 
              size="small" 
              type="danger" 
              text
              @click="removeFile(index)"
            >
              移除
            </el-button>
          </div>
        </div>
      </div>
      
      <div class="upload-actions">
        <el-button 
          type="primary" 
          :loading="isUploading"
          :disabled="fileList.length === 0"
          @click="startUpload"
        >
          开始上传
        </el-button>
        <el-button @click="clearFiles">清空列表</el-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { UploadFilled, Loading, Document } from '@element-plus/icons-vue'
import { useFileUpload } from '@/composables/useFileUpload'

interface Props {
  accept?: string
  maxSize?: number // 字节
  maxFiles?: number
  disabled?: boolean
  title?: string
  description?: string
  parentId?: number
}

const props = withDefaults(defineProps<Props>(), {
  accept: '*',
  maxSize: 1024 * 1024 * 1024, // 1GB
  maxFiles: 10,
  disabled: false,
  title: '拖拽文件到这里，或点击选择文件',
  description: '支持批量上传，可同时选择多个文件'
})

const emit = defineEmits<{
  success: [files: any[]]
  error: [error: string]
  progress: [progress: number]
}>()

// 状态管理
const isDragOver = ref(false)
const fileList = ref<File[]>([])
const fileInput = ref<HTMLInputElement>()

// 使用文件上传组合式函数
const { 
  isUploading, 
  uploadProgress, 
  uploadFiles 
} = useFileUpload()

// 计算属性
const acceptText = computed(() => {
  if (props.accept === '*') return '所有格式'
  return props.accept.replace(/\./g, '').toUpperCase()
})

const maxSizeText = computed(() => {
  return formatFileSize(props.maxSize)
})

// 拖拽事件处理
const handleDragOver = (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
}

const handleDragEnter = (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
  isDragOver.value = true
}

const handleDragLeave = (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
  isDragOver.value = false
}

const handleDrop = (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
  isDragOver.value = false
  
  if (props.disabled || isUploading.value) return
  
  const files = Array.from(e.dataTransfer?.files || [])
  addFiles(files)
}

// 文件选择处理
const triggerFileSelect = () => {
  if (props.disabled || isUploading.value) return
  fileInput.value?.click()
}

const handleFileSelect = (e: Event) => {
  const target = e.target as HTMLInputElement
  const files = Array.from(target.files || [])
  addFiles(files)
  target.value = '' // 清空input，允许重复选择同一文件
}

// 文件管理
const addFiles = (files: File[]) => {
  const validFiles = files.filter(file => validateFile(file))
  
  if (fileList.value.length + validFiles.length > props.maxFiles) {
    ElMessage.warning(`最多只能选择 ${props.maxFiles} 个文件`)
    return
  }
  
  fileList.value.push(...validFiles)
}

const validateFile = (file: File): boolean => {
  // 文件大小检查
  if (file.size > props.maxSize) {
    ElMessage.error(`文件 ${file.name} 超过大小限制 ${maxSizeText.value}`)
    return false
  }
  
  // 文件类型检查
  if (props.accept !== '*') {
    const acceptTypes = props.accept.split(',').map(type => type.trim())
    const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase()
    
    if (!acceptTypes.includes(fileExtension) && !acceptTypes.includes(file.type)) {
      ElMessage.error(`文件 ${file.name} 格式不支持`)
      return false
    }
  }
  
  return true
}

const removeFile = (index: number) => {
  fileList.value.splice(index, 1)
}

const clearFiles = () => {
  fileList.value = []
}

// 上传处理
const startUpload = async () => {
  if (fileList.value.length === 0) return
  
  try {
    const result = await uploadFiles(fileList.value, props.parentId)
    emit('success', result)
    clearFiles()
    ElMessage.success('文件上传成功')
  } catch (error) {
    emit('error', error as string)
    ElMessage.error('文件上传失败')
  }
}

// 工具函数
const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 监听上传进度
uploadProgress.value && emit('progress', uploadProgress.value)
</script>

<style lang="scss" scoped>
.file-upload-drag-drop {
  .upload-area {
    border: 2px dashed #d9d9d9;
    border-radius: 12px;
    padding: 40px 20px;
    text-align: center;
    cursor: pointer;
    transition: all 0.3s ease;
    background: #fafafa;
    position: relative;
    
    &:hover {
      border-color: #409eff;
      background: #f0f9ff;
    }
    
    &.drag-over {
      border-color: #409eff;
      background: #e6f7ff;
      transform: scale(1.02);
    }
    
    &.uploading {
      border-color: #67c23a;
      background: #f0f9ff;
      cursor: not-allowed;
    }
    
    &.disabled {
      opacity: 0.6;
      cursor: not-allowed;
    }
  }
  
  .upload-content {
    .upload-icon {
      margin-bottom: 16px;
      color: #409eff;
      
      .rotating {
        animation: rotate 2s linear infinite;
      }
    }
    
    .upload-text {
      margin-bottom: 16px;
      
      h3 {
        margin: 0 0 8px 0;
        font-size: 16px;
        color: #303133;
      }
      
      p {
        margin: 0;
        color: #606266;
        font-size: 14px;
      }
    }
    
    .upload-tips {
      p {
        margin: 4px 0;
        font-size: 12px;
        color: #909399;
      }
    }
  }
  
  .upload-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 0 20px 20px;
  }
  
  .file-list {
    margin-top: 20px;
    
    h4 {
      margin: 0 0 12px 0;
      font-size: 14px;
      color: #303133;
    }
    
    .file-items {
      border: 1px solid #ebeef5;
      border-radius: 8px;
      overflow: hidden;
      
      .file-item {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 12px 16px;
        border-bottom: 1px solid #f5f7fa;
        
        &:last-child {
          border-bottom: none;
        }
        
        .file-info {
          display: flex;
          align-items: center;
          gap: 12px;
          
          .file-icon {
            font-size: 20px;
            color: #409eff;
          }
          
          .file-details {
            .file-name {
              font-size: 14px;
              color: #303133;
              margin-bottom: 4px;
            }
            
            .file-size {
              font-size: 12px;
              color: #909399;
            }
          }
        }
      }
    }
    
    .upload-actions {
      margin-top: 16px;
      display: flex;
      gap: 12px;
    }
  }
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>
